package org.nstack.header.volume;

import org.nstack.header.storage.primary.PrimaryStorageInventory;
import org.nstack.header.storage.snapshot.VolumeSnapshotInventory;
import org.nstack.header.configuration.DiskOfferingInventory;
import org.nstack.header.configuration.PythonClassInventory;
import org.nstack.header.image.ImageInventory;
import org.nstack.header.query.ExpandedQueries;
import org.nstack.header.query.ExpandedQuery;
import org.nstack.header.search.Inventory;
import org.nstack.header.vm.VmInstanceInventory;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


@Inventory(mappingVOClass = VolumeVO.class)
@PythonClassInventory
@ExpandedQueries({
        @ExpandedQuery(expandedField = "vmInstance", inventoryClass = VmInstanceInventory.class,
                foreignKey = "vmInstanceUuid", expandedInventoryKey = "uuid"),
        @ExpandedQuery(expandedField = "snapshot", inventoryClass = VolumeSnapshotInventory.class,
                foreignKey = "uuid", expandedInventoryKey = "volumeUuid"),
        @ExpandedQuery(expandedField = "diskOffering", inventoryClass = DiskOfferingInventory.class,
                foreignKey = "diskOfferingUuid", expandedInventoryKey = "uuid"),
        @ExpandedQuery(expandedField = "primaryStorage", inventoryClass = PrimaryStorageInventory.class,
                foreignKey = "primaryStorageUuid", expandedInventoryKey = "uuid"),
        @ExpandedQuery(expandedField = "image", inventoryClass = ImageInventory.class,
                foreignKey = "rootImageUuid", expandedInventoryKey = "uuid"),
})
public class VolumeInventory implements Serializable {

    private String uuid;

    private String name;

    private String description;

    private String primaryStorageUuid;

    private String vmInstanceUuid;

    private String diskOfferingUuid;

    private String rootImageUuid;

    private String installPath;

    private String type;

    private String format;

    private Long size;

    private Long actualSize;

    private Integer deviceId;

    private String state;

    private String status;

    private Timestamp createDate;

    private Timestamp lastOpDate;

    private Boolean isShareable;

    public VolumeInventory() {
    }

    public VolumeInventory(VolumeInventory other) {
        this.uuid = other.uuid;
        this.name = other.name;
        this.description = other.description;
        this.primaryStorageUuid = other.primaryStorageUuid;
        this.vmInstanceUuid = other.vmInstanceUuid;
        this.diskOfferingUuid = other.diskOfferingUuid;
        this.rootImageUuid = other.rootImageUuid;
        this.installPath = other.installPath;
        this.type = other.type;
        this.format = other.format;
        this.size = other.size;
        this.actualSize = other.actualSize;
        this.deviceId = other.deviceId;
        this.state = other.state;
        this.status = other.status;
        this.createDate = other.createDate;
        this.lastOpDate = other.lastOpDate;
        this.isShareable = other.isShareable;
    }


    public static VolumeInventory valueOf(VolumeVO vo) {
        VolumeInventory inv = new VolumeInventory();
        inv.setRootImageUuid(vo.getRootImageUuid());
        inv.setCreateDate(vo.getCreateDate());
        inv.setDescription(vo.getDescription());
        inv.setInstallPath(vo.getInstallPath());
        inv.setName(vo.getName());
        inv.setPrimaryStorageUuid(vo.getPrimaryStorageUuid());
        inv.setSize(vo.getSize());
        inv.setActualSize(vo.getActualSize());
        inv.setState(vo.getState().toString());
        inv.setUuid(vo.getUuid());
        inv.setVmInstanceUuid(vo.getVmInstanceUuid());
        inv.setType(vo.getType().toString());
        inv.setDiskOfferingUuid(vo.getDiskOfferingUuid());
        inv.setCreateDate(vo.getCreateDate());
        inv.setLastOpDate(vo.getLastOpDate());
        inv.setDeviceId(vo.getDeviceId());
        inv.setStatus(vo.getStatus().toString());
        inv.setFormat(vo.getFormat());
        inv.setShareable(vo.isShareable());
        return inv;
    }

    public static List<VolumeInventory> valueOf(Collection<VolumeVO> vos) {
        List<VolumeInventory> invs = new ArrayList<>(vos.size());
        for (VolumeVO vo : vos) {
            invs.add(VolumeInventory.valueOf(vo));
        }
        return invs;
    }

    public Long getActualSize() {
        return actualSize;
    }

    public void setActualSize(Long actualSize) {
        this.actualSize = actualSize;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public String getDiskOfferingUuid() {
        return diskOfferingUuid;
    }

    public void setDiskOfferingUuid(String diskOfferingUuid) {
        this.diskOfferingUuid = diskOfferingUuid;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getPrimaryStorageUuid() {
        return primaryStorageUuid;
    }

    public void setPrimaryStorageUuid(String primaryStorageUuid) {
        this.primaryStorageUuid = primaryStorageUuid;
    }

    public String getVmInstanceUuid() {
        return vmInstanceUuid;
    }

    public void setVmInstanceUuid(String vmInstanceUuid) {
        this.vmInstanceUuid = vmInstanceUuid;
    }

    public String getInstallPath() {
        return installPath;
    }

    public void setInstallPath(String installPath) {
        this.installPath = installPath;
    }

    public String getType() {
        return type;
    }

    public void setType(String volumeType) {
        this.type = volumeType;
    }

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public boolean isAttached() {
        return this.vmInstanceUuid != null;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getRootImageUuid() {
        return rootImageUuid;
    }

    public void setRootImageUuid(String rootImageUuid) {
        this.rootImageUuid = rootImageUuid;
    }

    public Integer getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(Integer deviceId) {
        this.deviceId = deviceId;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Timestamp getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Timestamp createDate) {
        this.createDate = createDate;
    }

    public Timestamp getLastOpDate() {
        return lastOpDate;
    }

    public void setLastOpDate(Timestamp lastOpDate) {
        this.lastOpDate = lastOpDate;
    }

    public boolean isShareable() {
        return isShareable;
    }

    public void setShareable(boolean shareable) {
        isShareable = shareable;
    }
}
